package sk.tramtatiri.data.dao.jpa;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.TypedQuery;

import org.springframework.orm.jpa.JpaCallback;
import org.springframework.transaction.annotation.Transactional;

import sk.tramtatiri.data.dao.interfaces.UserInfoDao;
import sk.tramtatiri.data.dataobjects.UserInfo;

public class UserInfoDaoJPAImp extends AbstractDaoJPAImpl<UserInfo> implements
		UserInfoDao {

	public UserInfoDaoJPAImp() {
		super(UserInfo.class);
	}

	@Transactional
	public List<UserInfo> findAll() {
		return getJpaTemplate().execute(new JpaCallback<List<UserInfo>>() {
			public List<UserInfo> doInJpa(EntityManager em)
					throws PersistenceException {
				TypedQuery<UserInfo> query = em.createQuery(
						"select ui from UserInfo ui", UserInfo.class);
				return query.getResultList();
			}
		});
	}

	@Transactional
	public List<UserInfo> findAllByUserId(final long user_id) {
		return getJpaTemplate().execute(new JpaCallback<List<UserInfo>>() {
			public List<UserInfo> doInJpa(EntityManager em)
					throws PersistenceException {
				TypedQuery<UserInfo> query = em.createQuery(
						"select ui from UserInfo ui where ui.user_id='"
								+ user_id + "' order by ui.date asc",
						UserInfo.class);
				return query.getResultList();
			}
		});
	}

	@Transactional
	public UserInfo findByUserAndDate(final long user_id, final Date date) {
		try{
		return getJpaTemplate().execute(new JpaCallback<UserInfo>() {
			public UserInfo doInJpa(EntityManager em)
					throws PersistenceException {
				TypedQuery<UserInfo> query = em.createQuery(
						"select ui from UserInfo ui where ui.user_id='"
								+ user_id + "' and ui.date = :curr_date",
						UserInfo.class);
				query.setParameter("curr_date", date);
				return query.getSingleResult();
			}
		});
		}catch (Exception e) {
			return null;
		}
	}

	@Transactional
	public int countAll() {
		// TODO Auto-generated method stub
		return 0;
	}

	public UserInfo findName(String name) {
		// TODO Auto-generated method stub
		return null;
	}

	@Transactional
	public List<UserInfo> selectNewest(final long user_id) {
		return getJpaTemplate().execute(new JpaCallback<List<UserInfo>>() {
			public List<UserInfo> doInJpa(EntityManager em)
					throws PersistenceException {
				TypedQuery<UserInfo> query = em
						.createQuery(
								"select ui from UserInfo ui where ui.user_id = :userId order by ui.date desc limit 1",
								UserInfo.class);
				query.setParameter("userId", user_id);
				return query.getResultList();
			}
		});
	}

	@Transactional
	public List<UserInfo> selectLastXDays(final long user_id, final int days) {
		Calendar c = Calendar.getInstance();
		c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH) ,c.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
		c.add(Calendar.DAY_OF_MONTH, -days);
		final Date date = new Date(c.getTimeInMillis());
		return getJpaTemplate().execute(new JpaCallback<List<UserInfo>>() {
			public List<UserInfo> doInJpa(EntityManager em)
					throws PersistenceException {
				TypedQuery<UserInfo> query = null;
				if (days < 99) {
					query = em.createQuery("select ui from UserInfo ui where ui.user_id = :userId and ui.date >= :startDate order by ui.date asc",UserInfo.class);
					query.setParameter("startDate", date);
				} else {
					query = em.createQuery("select ui from UserInfo ui where ui.user_id = :userId order by ui.date asc",UserInfo.class);
				}
				query.setParameter("userId", user_id);
				return query.getResultList();
			}
		});
	}

	@Transactional
	public void delete(UserInfo o) {
		UserInfo ui = getJpaTemplate().find(UserInfo.class, o.getId());
		getJpaTemplate().remove(ui);
	}

	@Transactional
	public List<UserInfo> selectFirst(final long user_id) {
		return getJpaTemplate().execute(new JpaCallback<List<UserInfo>>() {
			public List<UserInfo> doInJpa(EntityManager em)
					throws PersistenceException {
				TypedQuery<UserInfo> query = em
						.createQuery(
								"select ui from UserInfo ui where ui.user_id = :userId order by ui.date asc limit 1",
								UserInfo.class);
				query.setParameter("userId", user_id);
				return query.getResultList();
			}
		});
	}

}
